package 
{
	import com.google.zxing.BarcodeFormat;
	import com.google.zxing.common.BitMatrix;
	import com.google.zxing.common.flexdatatypes.HashTable;
	import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
	import com.google.zxing.qrcode.QRCodeReader;
	import enum.DrawType;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.external.ExternalInterface;
	import flash.utils.getTimer;
	import flash.utils.setTimeout;
	import com.google.zxing.qrcode.QRCodeWriter;
	import ginger.code.QrCodeView;
	import com.google.zxing.EncodeHintType;
	
	/**
	 * ...
	 * @author Ning
	 */
	
	public class Main extends Sprite 
	{
		private var _codeBmp:Bitmap;
		public function Main():void 
		{
			if (stage) onAddedToStage();
			else addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
		}
		
		private function onAddedToStage(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
			// entry point
			setTimeout(init, 200);
		}
		private function init():void
		{
			this.stage.align = StageAlign.TOP_LEFT;
			this.stage.scaleMode = StageScaleMode.NO_SCALE;
			
			//限制的域名
			var domainName:String = '';
			if (stage.loaderInfo.url.indexOf(domainName) == -1)
			{
				throw new Error('不是有效的域名');
				return;
			}
			
			_codeBmp = new Bitmap();
			
			if (ExternalInterface.available)
			{
				ExternalInterface.addCallback('encode', encode);
				ExternalInterface.addCallback('draw', draw);
				ExternalInterface.call('isReady');
			}
		}
		private function encode(id:String,str:String, errlevel:String):void
		{
			var level:ErrorCorrectionLevel;
            switch(errlevel)
			{
				case 'H':
					level = ErrorCorrectionLevel.H;
					break;
				case 'M':
					level = ErrorCorrectionLevel.M;
					break;
				case 'Q':
					level = ErrorCorrectionLevel.Q;
					break;
				default :
					level = ErrorCorrectionLevel.L;
					break;
			}
			var start:int = getTimer();
			var qRCodeWriter:QRCodeWriter = new QRCodeWriter();
			qRCodeWriter.id = id;
			var hints:HashTable = new HashTable();
			hints.Add(EncodeHintType.ERROR_CORRECTION, level);
			hints.Add(EncodeHintType.CHARACTER_SET, 'UTF-8');
			var bitMatrix:BitMatrix = qRCodeWriter.encode(str,BarcodeFormat.QR_CODE, 0, 0,hints) as BitMatrix;
			var now:int = getTimer();
			returnQrCode(qRCodeWriter.id ,qRCodeWriter.data, now - start, qRCodeWriter.bitsize);
		}
		private function returnQrCode(id:String,bitdata:Array, encodetime:int, bitsize:String):void
		{
			trace('returnQrCode:' +id + ' ' + encodetime + ' ' + bitsize);
			if (ExternalInterface.available){
				ExternalInterface.call('returnQrCode',id, bitdata, encodetime, bitsize);
			}
		}
		
		private function draw(id:String,bitdata:Array,size:Number=50,color:String='0',qrtype:int=0):void
		{
			removeAll();
			var c:uint = uint(color);
			var w:Number = size;
			var h:Number = size;
			var bitW:Number = bitdata[0].length;
			var bitH:Number = bitdata.length;
			var pixelPerPoint:Number = h / bitH;
			
			trace(w+' '+h+' '+bitW+' '+bitH+' '+pixelPerPoint)
			
			
			var start:int = getTimer();
			if (qrtype == DrawType.VECTOR) {
				var shape:Shape = QrCodeView.vector(id,bitdata, pixelPerPoint, 0, 0xffffff, c);
				removeAll();
				addChild(shape);
				var now:int = getTimer();
			    returnDrawInfo(shape.name,now - start,shape.width);
				//trace(shape.width+' '+shape.height)
			}
			else if (qrtype == DrawType.BITMAP) {
				if (_codeBmp&&_codeBmp.bitmapData)
				    _codeBmp.bitmapData.dispose();
				pixelPerPoint = size;
				_codeBmp = QrCodeView.image(id, bitdata, pixelPerPoint, 0, 0xffffff, c);
				removeAll();
				addChild(_codeBmp);
				now = getTimer();
				returnDrawInfo(_codeBmp.name,now - start,_codeBmp.width);
				//trace(_codeBmp.width+' '+_codeBmp.height)
			}
			
		}
		private function returnDrawInfo(id:String,maptime:int,size:Number):void
		{
			trace('returnDrawInfo:' + id+' '+maptime+' '+size);
			if (ExternalInterface.available){
				ExternalInterface.call('returnDrawInfo', id, maptime,size);
			}
		}
		private function removeAll():void
		{
			while (this.numChildren > 0) {
			    this.removeChildAt(0);
			}
		}
	}
	
}